package com.example.spring.security.demo.config.validate.image;

import com.alibaba.fastjson.JSONObject;
import com.example.spring.security.demo.config.validate.ValidateCodeException;
import com.example.spring.security.demo.config.validate.image.ImageCode;
import com.example.spring.security.demo.controller.ValidateCodeController;
import com.example.spring.security.demo.properties.SecurityConstants;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;
import org.apache.commons.lang.StringUtils;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 校验验证码的过滤器
 *
 * @author zhailiang
 *
 */
//定义过滤器，一个请求可以被请求过滤一次
@Component
public class ImageValidateCodeFilter extends OncePerRequestFilter implements InitializingBean {

    @Autowired
    private SimpleUrlAuthenticationFailureHandler authenticationFailureHandler;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private Set<String> urls = new HashSet<>();

    private AntPathMatcher pathMatcher = new AntPathMatcher();


    @Override
    public void afterPropertiesSet() throws ServletException {
        super.afterPropertiesSet();
        String[] configUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens("/authentication/form",",");
        for (String url : configUrls) {
            urls.add(url);
        }
        urls.add("/authentication/from");
        urls.add("/sigin");

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {

        /*if(StringUtils.equals("/authentication/from",request.getRequestURI())
                && StringUtils.equalsIgnoreCase(request.getMethod(),"post")){*/
        boolean actionFlag = false;
        for (String url : urls) {
            if(pathMatcher.match(url,request.getRequestURI())) {
                actionFlag = true;
                break;
            }
        }

        if(actionFlag){
            try {
                validate(new ServletWebRequest(request));
            }catch (ValidateCodeException e){
                authenticationFailureHandler.onAuthenticationFailure(request,response,e);
            }
        }
        chain.doFilter(request,response);
    }

    private void validate(ServletWebRequest request) throws ValidateCodeException{

        String codeInRequest;
        try {
            codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(),"imageCode");
        } catch (ServletRequestBindingException e) {
            throw new ValidateCodeException("获取验证码的值失败");
        }

        String codejson = stringRedisTemplate.opsForValue().get(SecurityConstants.DEFAULT_PARAMETER_NAME_CODE_IMAGE);
        if (StringUtils.isEmpty(codeInRequest)) {
            throw new ValidateCodeException("图片验证码的值不能为空");
        }

        if (!StringUtils.equals(codejson, codeInRequest)) {
            throw new ValidateCodeException("图片验证码不匹配");
        }

        stringRedisTemplate.delete(codeInRequest);
    }
}
